MS-DOS:1.25:Z-100 OEM:1.01:8-11-1983/disk01/PSC.ASM
Print Screen Utility assembler source file. File content PAGE ,132 TITLE PSC - Print Screen Utility ;*** PSC - Print Screen Utility ; ; PSC is a print screen utility. It intercepts INT 5 from ; the BIOS (generated when is struck), and prints ; the contents of the screen onto the PRN device. ; ; Zenith Data Systems ; December 15, 1982 ; Copyright © 1982, Zenith Data Systems ; ; To assemble: ; ; MASM PSC; ; LINK PSC; ; EXE2BIN PSC .COM ; ERASE PSC.EXE ; ; To execute: ; ; PSC ; ; To activate: ; ; Press SHIFT and F12 simultaneously. ; ; Once PSC has been executed, it remains permanently in RAM and ; does not need to be executed again. ; FALSE = 0 TRUE = NOT FALSE INCLUDE DEFMS.ASM INCLUDE DEFMTR.ASM page ; The next 2 switches should be set to TRUE and TRUE for: ; ; TI-810, H/Z-25, MX-80, and Diablo. If you have a different ; printer, you may want to check to see if your printer will ; automatically generate either CR or LF or both at then end ; of a physical line (auto wrap). If so, you must set either ; or both of these switches to FALSE. ; GENLF = TRUE ; if to generate LF at end of line GENCR = TRUE ; if to generate CR at end of line COLUMNS = 80 ; Characters/line CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE ORG 100H ;* Entry point ; BEGIN: JMP NEAR PTR START ;* INT 5 handler ; INT_5: PUSH DS ; Save his data segment PUSH AX MOV CS:INT_SP,SP MOV CS:INT_SS,SS ; Save his stack MOV AX,CS MOV SS,AX ; Set local stack MOV SP,OFFSET INT_STACK STI ; Now allow interrupts to come in PUSH ES PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI MOV DS,AX MOV ES,AX ; Set up my segments CALL INT_SIZE ; Size screen CALL INT_SCRN ; Process the screen POP DI POP SI POP DX POP CX POP BX POP ES CLI ; INTs off while messing around MOV AX,INT_SP MOV SP,AX MOV AX,INT_SS ; Restore his stack MOV SS,AX POP AX POP DS IRET ; Back to BIOS INT_SS DW 0 ; Saved stack values INT_SP DW 0 INT_CX DW 0 ; Current X location INT_CY DW 0 ; Current Y location MYCHR DW 0 ; Character at position MYLINE DB 82 DUP (?) ; Line buffer LINES DW 0 ; Number of lines valid on screen DW 128 DUP (?) INT_STACK LABEL NEAR ; Internal stack ;* INT_SIZE - Size Screen ; ; INT_SIZE checks to see if the 25th line is enabled. If ; it is, LINES is modified to be 25, so all lines are ; printed ; INT_SIZE: MOV WORD PTR LINES,24 ; Assume not MOV SI,OFFSET INT_SIZA ; Print first line CLI ; Don't interrupt me now CALL INT_PLINE ; Output line PUSH DS XOR AX,AX MOV DS,AX ; Get data segment MOV DS,DS:MTR_DS MOV AL,DS:MTR_VERP ; AL = horiz. position of cursor POP DS PUSH AX MOV SI,OFFSET INT_SIZB ; Put cursor back CALL INT_PLINE ; Output line STI POP AX CMP AL,24 JNZ INT_SIZ1 ; If not on 24th line ; Cursor moved to 25th line, must be enabled INC WORD PTR LINES INT_SIZ1: RET INT_SIZA LABEL NEAR DB 01BH,'j' ; Save cursor DB 01BH,'Y',25+31,1+31 ; Go here DB -1 ; End of message INT_SIZB LABEL NEAR DB 01BH,'k' ; Restore cursor DB -1 ;* INT_PLINE - Print line on console ; INT_PLINE: MOV AL,BYTE PTR SI ; Get character INC SI ; Bump for next time CMP AL,-1 JZ INT_PLIN1 ; If end of text PUSH SI CALL FAR PTR BIOS_CONOUT ; Output it POP SI JMP SHORT INT_PLINE ; Do next INT_PLIN1: RET ;* INT_SCRN - Interrupt time Screen Processor ; INT_SCRN: MOV WORD PTR INT_CX,0 MOV WORD PTR INT_CY,0 ; Show line 0, column 0 MOV SI,OFFSET MYLINE ; Save one line here ; Do a screen line INT_SCRN1: PUSH DS PUSH SI PUSH DS MOV AX,OFFSET MYCHR PUSH AX ; 32 bit address for character PUSH WORD PTR INT_CY ; Vertical location PUSH WORD PTR INT_CX ; Horizontal location XOR AX,AX MOV DS,AX MOV DS,DS:MTR_DS ; Pointer to MTR data area CALL DS:DWORD PTR MTR_RDC ; Read it POP SI POP DS MOV AL,BYTE PTR MYCHR ADD AL,' ' ; AL = character ; AL = character, H19 graphics are numbered 80H - A1H AND AL,07FH ; Make it printable CMP AL,' ' JNC INT_SCRN2 ; If printable MOV AL,' ' ; Not printable, make it a space INT_SCRN2: ; Save character MOV BYTE PTR SI,AL INC SI INC WORD PTR INT_CX ; Go to next character CMP WORD PTR INT_CX,COLUMNS JC INT_SCRN1J ; If can do more ; End of character line, print the whole thing MOV SI,OFFSET MYLINE MOV WORD PTR INT_CX,0 ; Reset it INT_SCRN3: MOV AL,BYTE PTR SI ; Get character INC SI PUSH SI CALL FAR PTR BIOS_PRINT ; Print it POP SI INC WORD PTR INT_CX ; Do next CMP WORD PTR INT_CX,COLUMNS JC INT_SCRN3 ; Line output, follow with CR/LF PUSH SI IF GENLF MOV AL,0AH CALL FAR PTR BIOS_PRINT ; do LF ENDIF IF GENCR MOV AL,0DH CALL FAR PTR BIOS_PRINT ; do CR ENDIF POP SI MOV WORD PTR INT_CX,0 ; Start a new line MOV SI,OFFSET MYLINE ; here INC WORD PTR INT_CY ; next horizontal line MOV AX,WORD PTR INT_CY CMP AX,LINES ; end of screen? JC INT_SCRN1J ; nope, continue RET ; Stepping stone for near conditional jumps INT_SCRN1J: JMP NEAR PTR INT_SCRN1 ;* Mark end of resident portion INT_END LABEL NEAR ;* Main entry point ; START: MOV SP,OFFSET INT_STACK ; Good place for it PUSH DS XOR AX,AX MOV DS,AX ; Clear DS MOV SI,5*4 ; SI points to interrupt CLI MOV WORD PTR SI,OFFSET INT_5 MOV WORD PTR SI+2,CS ; Set my interrupt vector STI POP DS MOV DX,OFFSET INT_END ; LWA of resident portion INT 27H CODE ENDS END BEGIN ����������������������������������������������������������������������������������